/**********************************************
/ file : ifft.sc
/ Author : Jungmin Park
/ Date : 5/5/2011 
/ Specification Model of the radix4 IFFT  
***********************************************/
#include <math.h>
#include <stdio.h>
#define PI 3.141592
import "c_double_handshake";

behavior ifft_radix4 (i_receiver IR1, i_receiver IR2, i_sender IS1, i_sender IS2)
{
  float x_re [16];
  float x_im [16];
  float y_re [16];
  float y_im [16];
  int i;
  int j;
  int N1, N2, k1;
  float bfly_re [4];
  float bfly_im [4];  

    
  void main (void)
  {
    while (1) {
      for (i=0; i<16; i++) {
        IR1.receive (x_re+i, sizeof(float));
        IR2.receive (x_im+i, sizeof(float));
      }

    for (i=0; i<2; i++)
	{
		if (i == 0 ) 
		{ 
			N1 = 1;
			N2 = 4;
		}
		else
		{
			N1 = 4;
			N2 = 1;
		}
       /** Do 4 Point DFT */ 
       for (j=0; j<4; j++)
        {		
	       bfly_re[0] = (x_re[N1*j] + x_re[N2+N1*j] + x_re[N2*2+N1*j] + x_re[N2*3+N1*j]);
	       bfly_im[0] = (x_im[N1*j] + x_im[N2+N1*j] + x_im[N2*2+N1*j] + x_im[N2*3+N1*j]);

	       bfly_re[1] = (x_re[N1*j] + x_im[N2+N1*j] - x_re[N2*2+N1*j] - x_im[N2*3+N1*j]);
	       bfly_im[1] = (x_im[N1*j] - x_re[N2+N1*j] - x_im[N2*2+N1*j] + x_re[N2*3+N1*j]);

	       bfly_re[2] = (x_re[N1*j] - x_re[N2+N1*j] + x_re[N2*2+N1*j] - x_re[N2*3+N1*j]);
	       bfly_im[2] = (x_im[N1*j] - x_im[N2+N1*j] + x_im[N2*2+N1*j] - x_im[N2*3+N1*j]);

	       bfly_re[3] = (x_re[N1*j] - x_im[N2+N1*j] - x_re[N2*2+N1*j] + x_im[N2*3+N1*j]);
	       bfly_im[3] = (x_im[N1*j] + x_re[N2+N1*j] - x_im[N2*2+N1*j] - x_re[N2*3+N1*j]);

	
	       /** In-place results */
   
	       for (k1=0; k1<4; k1++)
	       {
	          		      
	          x_re[N2*k1+N1*j] = bfly_re[k1]*cos(2*PI*(1-i)*j*k1/16.0) - bfly_im[k1]*sin(2*PI*(1-i)*j*k1/16.0) ;
	          x_im[N2*k1+N1*j] = bfly_im[k1]*cos(2*PI*(1-i)*j*k1/16.0) + bfly_re[k1]*cos(2*PI*(1-i)*j*k1/16.0) ;
	       }
         }
	}
    
     for (i=0; i<4; i++)
	{
		for (j=0; j<4; j++)
		{
                 	y_re[i+j*4] = x_re [i*4+j]/16.0;
			y_im[i+j*4] = x_im [i*4+j]/16.0;
		 }
		 
	}

     for (i=0; i<16; i++)
     {
         IS1.send (y_re+i, sizeof(float));
         IS2.send (y_im+i, sizeof(float));
     }
   }
  }
};     
